package net.coding.li709.materialrefresher.model;

import com.flowpowered.math.vector.Vector3d;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import net.coding.li709.materialrefresher.keys.FlanData;
import net.coding.li709.materialrefresher.manage.GiftManager;
import net.coding.li709.materialrefresher.utils.EntityUtils;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.event.CauseStackManager;
import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.cause.entity.spawn.SpawnTypes;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import java.util.Random;

@Data
@ConfigSerializable
@RequiredArgsConstructor
public class SpawnLoc {

    @Setting
    private String name;
    @Setting
    private String box;
    @Setting
    private int minTick;
    @Setting
    private int maxTick;
    @Setting
    private Vector3d pos;
    @Setting
    private String world;

    //冷却CD
    private Cooling cooling=new Cooling();

    /**
     * 刷新点状态
     */
    private int state;

    private static Random r=new Random();

    //生成倒计时，如果倒计时1秒后还没生成，则进入（循环10秒判断重新生成状态，直到生成成功）
    private Cooling spawnCooling=new Cooling();

    public SpawnLoc(String name, String box,Vector3d pos,String world, int minTick, int maxTick) {
        this.name = name;
        this.box = box;
        this.minTick = minTick;
        this.maxTick = maxTick;
        this.pos = pos;
        this.world=world;
    }

    public void init(){
        //刚启动生成点的初始化
        reset();
    }
    /**
     * 生成掉落物
     */
    public void spawn(){
        ItemStack itemStack = GiftManager.useBox(box);
        World world = Sponge.getServer().getWorld(this.world).get();
        Location<World> loc=new Location<>(world,pos);

        Entity entity = EntityUtils.createEntity("flansmod:CustomItem", loc);

        //写入掉落的物品
        entity.offer(Keys.REPRESENTED_ITEM, itemStack.createSnapshot());
        //写入flan相关数据，禁止自动拾取，写入生成点ID
        entity.offer(new FlanData(true, name));
        try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
            frame.addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.PLUGIN);
            world.spawnEntity(entity);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 更新
     */
    public void onUpdate(){
        //未被拾取，不更新 ,并且已生成
        if (state==2){
            return;
        }

       //冷却结束，如果是已拾取，并且到了刷新时间，则生成物品
        if (cooling.onUpdate()){
            state=1;
            spawn();
            //生成倒计时，如果倒计时1秒后还没生成，则进入（循环10秒判断重新生成状态，直到生成成功）
            spawnCooling.startCooling(100);
            return;
        }

        //如果处于即将生成状态,并且倒计时1秒结束还没生成，则重新计时10秒生成
        if (state==1&&spawnCooling.onUpdate()){
            reset(200);
        }
    }

    /**
     * 开始冷却时间
     */
    public void reset(){
        state=0;
        cooling.startCooling(r.nextInt(maxTick-minTick+1)+minTick);
    }
    /**
     * 开始冷却时间
     */
    public void reset(int tick){
        state=0;
        cooling.startCooling(tick);
    }
    /**
     *  将生成点改为未拾取状态
     */
    public void changeSpawnLocState(){
        state=2;
    }
}
